﻿using System;
using Airborne.ScrumPoker.Model.TeamFoundation;
using Airborne.ScrumPoker.Module.Events;
using Airborne.ScrumPoker.Module.Host.Services;
using Airborne.ScrumPoker.Module.Host.Tests.Mocks;
using Microsoft.VisualStudio.TestTools.UnitTesting;

namespace Airborne.ScrumPoker.Module.Host.Tests.Services
{
    [TestClass]
    public class ConnectionManagerTestFixture
    {
        [TestMethod]
        public void CanRegisterTest()
        {
            ConnectionManager manager = new ConnectionManager();
            MockScrumPokerServerConnection connection = new MockScrumPokerServerConnection() { ClientName = "MyName" };
            Assert.IsTrue(manager.CanRegister(connection));
            manager.Register(connection);
            Assert.IsFalse(manager.CanRegister(connection));
            manager.Unregister(connection);
        }

        [TestMethod]
        public void ClientSubscribeTest()
        {
            ConnectionManager manager = new ConnectionManager();
            MockScrumPokerServerConnection connection = new MockScrumPokerServerConnection() { ClientName = "MyName" };
            bool handlerCalled = false;
            EventHandler<GenericEventArgs<string>> handler = new EventHandler<GenericEventArgs<string>>(delegate(object sender, GenericEventArgs<string> e) { Assert.AreEqual(connection.ClientName, e.Data); handlerCalled = true; });
            manager.ClientSubscribed += handler;
            manager.Register(connection);
            manager.ClientSubscribed -= handler;
            manager.Unregister(connection);
            Assert.IsTrue(handlerCalled);

        }

        [TestMethod]
        public void ClientUnsubscribeTest()
        {
            ConnectionManager manager = new ConnectionManager();
            MockScrumPokerServerConnection connection = new MockScrumPokerServerConnection() { ClientName = "MyName" };
            bool handlerCalled = false;
            EventHandler<GenericEventArgs<string>> handler = new EventHandler<GenericEventArgs<string>>(delegate(object sender, GenericEventArgs<string> e) { Assert.AreEqual(connection.ClientName, e.Data); handlerCalled = true; });
            manager.ClientUnsubscribed += handler;
            manager.Register(connection);
            manager.Unregister(connection);
            manager.ClientUnsubscribed -= handler;
            Assert.IsTrue(handlerCalled);
        }

        

        [TestMethod]
        public void TimerStartTest()
        {
            ConnectionManager manager = new ConnectionManager();
            MockScrumPokerServerConnection connection = new MockScrumPokerServerConnection();
            manager.Register(connection);
            manager.StartTimer(20);

            Assert.IsTrue(connection.TimerStarted);
            Assert.AreEqual(20, connection.TimerDuration);
            manager.Unregister(connection);
        }

        [TestMethod]
        public void TimerStopTest()
        {
            ConnectionManager manager = new ConnectionManager();
            MockScrumPokerServerConnection connection = new MockScrumPokerServerConnection();
            manager.Register(connection);
            manager.StopTimer();
            
            Assert.IsFalse(connection.TimerStoped,"Can not stop a timer that has not started!");

            manager.StartTimer(20);
            Assert.IsTrue(connection.TimerStarted);
            Assert.IsFalse(connection.TimerStoped);

            manager.StopTimer();
            Assert.IsTrue(connection.TimerStoped);

            manager.Unregister(connection);
        }

        [TestMethod]
        public void WorkItemSelectedTest()
        {
            ConnectionManager manager = new ConnectionManager();
            MockScrumPokerServerConnection connection = new MockScrumPokerServerConnection();
            manager.Register(connection);
            MockTeamWorkItem item = new MockTeamWorkItem() { Title = "Work Item Title" };
            manager.SelectWorkItem((ITeamWorkItem)item);

            Assert.IsTrue(connection.WorkItemSelected);
            Assert.AreEqual(item.Title, connection.WorkItemTitle);
            connection.WorkItemSelected = false;
            connection.WorkItemTitle = string.Empty;

            manager.StartTimer(20);

            manager.SelectWorkItem((ITeamWorkItem)item);

            Assert.IsFalse(connection.WorkItemSelected);
        }


        [TestMethod]
        public void ClientVoteTest()
        {
            ConnectionManager manager = new ConnectionManager();
            MockScrumPokerServerConnection connection = new MockScrumPokerServerConnection();
            manager.Register(connection);

            int vote = 10;
            bool handlerCalled = false;

            EventHandler<ClientVotedEventArgs> handler = new EventHandler<ClientVotedEventArgs>(delegate(object sender, ClientVotedEventArgs e) { 
                Assert.AreEqual(e.Client, connection.ClientName);
                Assert.AreEqual(vote, e.Vote);
                handlerCalled = true; });

            manager.ClientVote += handler;

            connection.Vote(vote);

            Assert.IsTrue(handlerCalled);

            manager.Unregister(connection);
        }
    }
}
